<?php
/**
 * 
 * ============================================================================
 * 版权所有: (c) 2009-2011，<UEShop Inc>，并保留所有权利。
 * 网站地址: http://www.ueshop.cn
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用；
 * 不允许对程序代码以任何形式任何目的的再发布。
 * ============================================================================
 *
 * @author      cmpan
 * @copyright   Copyright (c) 2009-2011 UEShop Inc. (http://www.ueshop.cn)
 * @license     http://www.ueshop.cn/1_0.txt
 */
abstract class UE_DB_Abstract extends UE_Object {
	/**
	 * 返回的数组类型下标为关联数组格式（以字段名为下标）的类型
	 */
	const ROW_TYPE_ASSOC  = 1;  // == MYSQL_ASSOC

	/**
	 * 返回的数组类型下标为整数格式（以整数下标，从0开始）
	 */
	const ROW_TYPE_NUM    = 2;  // == MYSQL_NUM

	/**
	 * 返回的数组类型下标为ROW_TYPE_ASSOC和ROW_TYPE_NUM两种格式
	 */
	const ROW_TYPE_BOTH   = 3;  // == MYSQL_BOTH  
	
	/**
	 * 数据库当前页面连接次数,每次实行查询语句的时候,++
	 * @var int
	 */
	public $execNums = 0;

    /**
	 * 数据库连接
	 * @var res
	 */
	protected $_link = null;

    /**
	 * 使用的数据库名，如： mydata
	 * @var string
	 */
	protected $_db = '';
	
	/**
	 *  获取数据库版本
	 *
	 * @return string
	 */
	public abstract function version();
		
	/**
	 * 选择使用数据库
	 * 
	 * @param string $db 数据库名
	 */
	public abstract function selectDB($db = '');


	/**
	 * 简单查询
	 *
	 * @param String $sql
	 * @return mixed
	 */
	public abstract function query($sql);

	/**
	 * 向 数据库 发送一条 SQL 查询，并不获取和缓存结果的行
	 *
	 * @param String $sql
	 * @param bool $allowCache 是否允许启用缓存 cfg('db_cache') 起作用后才有用
	 * @return array $row  结果记录集
	 */
	public abstract function getOne($sql, $allowCache = false);

	/**
	 * 向 数据库 发送一条 SQL 查询，并不获取和缓存结果的行
	 *
	 * @param String $sql
	 * @param bool $allowCache 是否允许启用缓存 cfg('db_cache') 起作用后才有用
	 * @return array $rows  结果记录集
	 */
	public abstract function getAll($sql, $allowCache = false);
	public abstract function getfirstField($sql, $allowCache = false);

	/**
	 * 取得前一次 数据库 操作所影响的记录行数
	 *
	 * @return int 行数
	 */
	public abstract function affectedRows();

	/**
	 * 取得结果集中行的数目
	 *
	 * @param String $query
	 * @return int 行数
	 */
	public abstract function numRows($sql);

	/**
	 * 释放数据库结果内存
	 * 仅需要在考虑到返回很大的结果集时会占用多少内存时调用。
	 * 在脚本结束后所有关联的内存都会被自动释放。
	 *
	 * @param resource $resource 
	 * @return bool
	 */
	public abstract function freeResult(&$resource);

	/**
	 * 取得上一步 INSERT 操作产生的 ID
	 *
	 * @return int $id
	 */
	public abstract function lastInsertId();
	
	//public abstract function getLastErr();

	/**
	 * 关闭数据库
	 *
	 * @return
	 */
	public abstract function close();

	/**
	 * 更新一行或多行
	 *
	 * @param string $table  要更新的表
	 * @param string $key    更新参照的字段名
	 * @param string $value  更新参照的字段值
	 * @param array $array   更新的数据array('字段'=>'值'[,...])
	 * @param int $limit     更新多少条，默认全部更新对应的列
	 * @return bool
	 */
	public abstract function update($table, $key, $value, $array, $limit = 0);

	/**
	 * 插入一条记录
	 *
	 * @param string $table  插入哪个表
	 * @param array $array   插入的数据结构（以字段名为下标的，插入值为值的关联数组）
	 * @return bool
	 */
	public abstract function insertRow($table, $array);

	/**
	 * 删除一行或多行
	 *
	 * @param string $table   表名
	 * @param string $key     条件的列名
	 * @param string $value   条件的值
	 * @param int $limit      删除多少行
	 * @return bool
	 */
	public abstract function delete($table, $key, $value, $limit = 0) ;

	/**
	 * @return array
	 */
	public abstract function errMsgs() ;

	/**
	 * SHOW COLUMNS FROM `my_table`
	 * 
	 * @param string $table  表名
	 * @param string $dbName 数据库名，如果为空则选择当前使用的数据库
	 */
	public abstract function getTableInfo($table, $dbName = '');

    /**
	 * 替换表名的前缀
	 * sql中写表的前缀一律用 yl_, 运行的时候转换成配置文件中使用的前缀
	 */
	public static function prefix($sql) {
		return preg_replace('/\s(.+?)ue_(.+?)([,|\s]?)/', 
				' $1' . cfg('table_prefix') . '$2$3', $sql);
	}

	/**
	 * 从文件载入SQL
	 *
	 * @param string $file  (表单传来)文件的路径
	 * @return int   执行了多少条sql
	 */
	public static function insertFile($file) {
		$readfiles = file_get_contents($file);
	
		$detail = explode("\n", $readfiles);
		$count = count($detail);
		for($j = 0; $j < $count; $j++) {
			$ck = substr($detail[$j], 0, 4);
			if(ereg("#", $ck) || ereg("--", $ck)) {
				continue;
			}
			$array[] = $detail[$j];
		}
		$read = implode("\n", $array);
		$sql = str_replace("\r", '', $read);
		$detail = explode(";\n", $sql);
		$count = count($detail);
		for($i = 0; $i < $count; $i++) {
			$sql = str_replace("\r", '', $detail[$i]);
			$sql = str_replace("\n", '', $sql);
			$sql = trim($sql);
			if($sql) {
				$this->query($sql);
				$check++;
			}
		}
		return $check;
	}
	
	/**
	 * 获取总SQL查询的总记录数
	 *
	 * @param string $sql
	 * @return int
	 */
	function getSelectTotals($sql) {
		$sql = preg_replace('/SELECT([^from].*)from/i', "SELECT COUNT(*) as count FROM ", $sql);
		return $this->getfirstField($sql);
	}
}